﻿using CNav.Business;
using CNav.Business.Validation;
using CNav.Common;
using CNav.DataEntity;
using CNav.Domain;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CNav.Business.Services
{
    public interface IProductService
    {
        ResponseData<bool> AddProduct(Product product);
        ResponseData<Product> UpdateProduct(Product product);
        ResponseData<bool> DeleteProduct(int id);
        ResponseData<List<Product>> GetProducts();
        ResponseData<Product> GetProduct(int id);
    }

    public class ProductService : ServiceBase, IProductService
    {
        public ResponseData<bool> AddProduct(Product product)
        {
            var response = new ResponseData<bool>();

            var validator = new ProductValidation();
            var result = validator.Validate(product);
            if (result.IsValid)
            {
                var tempProduct = Context.Get<ProductDto>(p => p.Name == product.Name).ToList().FirstOrDefault();

                if (tempProduct != null)
                {
                    response.Error = new[] { "Duplicate product." };
                    return response;
                }

                var productDto = new ProductDto();

                productDto.Name = product.Name.ToUpper();
                productDto.Description = product.Description;
                productDto.AdminComment = product.AdminComment;
                productDto.Category = product.Category;
                productDto.SubCategory = product.SubCategory;
                productDto.CreatedOnUtc = DateTime.UtcNow;

                Context.Repository<ProductDto>().Add(productDto);
                Context.Commit();

                response.Data = true;
                return response;
            }
            response.Error = result.ErrorList();
            return response;
        }

        private bool ProductExist(int id)
        {
            ProductDto productDto = Context.Get<ProductDto>(p => p.ID == id).ToList()
                  .FirstOrDefault();

            return productDto != null;
        }

        public ResponseData<Product> UpdateProduct(Product product)
        {
            var response = new ResponseData<Product>();

            var validator = new ProductValidation();
            var result = validator.Validate(product);
            if (result.IsValid)
            {
                if (ProductExist(product.ID))
                {
                    var productDto = Context.Get<ProductDto>(c => c.ID == product.ID).ToList().FirstOrDefault();

                    productDto.Name = product.Name.ToUpper();
                    productDto.Description = product.Description;
                    productDto.AdminComment = product.AdminComment;
                    productDto.Category = product.Category;
                    productDto.SubCategory = product.SubCategory;
                    productDto.UpdatedOnUtc = DateTime.UtcNow;

                    Context.Repository<ProductDto>().Update(productDto);
                    Context.Commit();
                    response = GetProduct(product.ID);

                    return response;
                }
                response.Error = new[] { "Product provided does not exist." };
                return response;
            }
            response.Error = result.ErrorList();
            return response;
        }

        public ResponseData<bool> DeleteProduct(int id)
        {
            var response = new ResponseData<bool>();

            var productDto = Context.Get<ProductDto>(c => c.ID == id).ToList().FirstOrDefault();
            if (productDto != null)
            {
                Context.Repository<ProductDto>().Delete(productDto);
                Context.Commit();

                response.Data = true;
                return response;
            }
            response.Error = new[] { "Product provided does not exist." };
            return response;
        }

        public ResponseData<List<Product>> GetProducts()
        {
            var response = new ResponseData<List<Product>>();
            var productDtos = Context.Get<ProductDto>().ToList();

            response.Data = productDtos.Select(p => new Product
            {
                ID = p.ID,
                AdminComment = p.AdminComment,
                Category = p.Category,
                SubCategory = p.SubCategory,
                Name = p.Name,
                CreatedOnUtc = p.CreatedOnUtc,
                UpdatedOnUtc = p.UpdatedOnUtc,
                Description = p.Description
            }).ToList();
            return response;
        }

        public ResponseData<Product> GetProduct(int id)
        {
            var response = new ResponseData<Product>();
            var productDto = Context.Get<ProductDto>(p => p.ID == id).ToList().FirstOrDefault();
            if (productDto != null)
            {
                var product = new Product();

                product.ID = productDto.ID;
                product.AdminComment = productDto.AdminComment;
                product.Category = productDto.Category;
                product.SubCategory = productDto.SubCategory;
                product.Name = productDto.Name;
                product.CreatedOnUtc = productDto.CreatedOnUtc;
                product.UpdatedOnUtc = productDto.UpdatedOnUtc;
                product.Description = productDto.Description;

                response.Data = product;
                return response;
            }
            response.Error = new[] { "Product id does not exist." };
            return response;
        }
    }
}